/**
 * @Author wangyl
 * @E-mail wangyl@dsgdata.com
 **/
package com.wyl.xue.admin.security.filter;

import cn.hutool.core.util.ObjectUtil;
import com.wyl.xue.admin.security.UserInfoJwt;
import com.wyl.xue.admin.security.user.SecurityUserInfo;
import com.wyl.xue.admin.system.mybatis.service.SystemUsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName: JwtAuthenticationTokenFilter
 * @Function: JWT过滤器 验证jwt的有效性
 * @Date: 2019/12/17 21:18
 * @author wyl
 * @version V1.0
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private SystemUsersService systemUsersService;

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;


    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            String token = UserInfoJwt.getToken(httpServletRequest);
            if (ObjectUtil.isNotNull(token)) {
                Map UserInfo = UserInfoJwt.UserInfo(token);
                List<Map> permissions = (List<Map>) UserInfo.get("authorities");
                List<Object> authority = permissions.parallelStream()
                                                    .map(permission -> permission.get("authority"))
                                                    .collect(Collectors.toList());
                List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(authority.toArray(new String[0]));
                SecurityUserInfo securityUser = new SecurityUserInfo(Long.valueOf(UserInfo.get("userid")
                                                                                          .toString()), UserInfo.get("sub")
                                                                                                                .toString(), null, null);
                securityUser.setAuthorities(authorities);
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(securityUser, null, authorities);
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                SecurityContextHolder.getContext()
                                     .setAuthentication(authenticationToken);
            }
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        }
        catch (Exception e) {
            resolver.resolveException(httpServletRequest, httpServletResponse, null, e);
        }

    }
}
